home *** CD-ROM | disk | FTP | other *** search
- /*=========================================================================
-
- ATOC function declarations module
-
- =========================================================================*/
-
- #include <stdio.h>
- #include <ctype.h>
- #include "atoc.h"
-
- /**/ /* this version requires that function and all args are on one line */
-
- /* #define TESTING */
-
- #define MAXARGS 32 /* max args one function can have */
-
-
- /*-------------------------------------------------------------------------
- local global variables
- -------------------------------------------------------------------------*/
- PRIVATE char *args[ MAXARGS ] = { /* individual arguments */
- NULL
- };
- PRIVATE char temp[ MAXLINELENGTH ]; /* temp buffer */
-
-
- /*-------------------------------------------------------------------------
- function( s ) looks for function declarations or prototypes and expands or
- removes their arguments.
- -------------------------------------------------------------------------*/
- function( s )
- char *s;
- {
- char *start, *stop, *strchr(), *strrchr();
- char *cp, *dp, *malloc();
- char *argname();
- int ansi_style, i;
-
- if ( isfunction( s ) )
- {
- start = strchr( s, '(' ) + 1;
- stop = strrchr( s, ')' );
- if ( strchr( s, ';' ) == NULL ) /* declaration */
- {
- /* make list of arguments in *args[] */
- i = 0;
- for ( cp = start; cp < stop; ++cp )
- {
- while ( cp < stop && isspace( *cp ) )
- ++cp;
- if ( cp < stop )
- {
- dp = temp;
- while ( cp < stop && *cp != ',' )
- *dp++ = *cp++;
- *dp = '\0';
- /* strip trailing spaces */
- for ( --dp; dp >= temp && isspace( *dp ); --dp )
- *dp = '\0';
- if ( ( args[ i ] = malloc( strlen( temp ) + 1 ) ) != NULL )
- {
- strcpy( args[ i ], temp );
- ++i;
- }
- }
- }
- args[ i ] = NULL;
-
- /* see if ANSI or K&R style */
- /* ANSI will have white space within arg */
- ansi_style = FALSE;
- for ( cp = args[ 0 ]; *cp; ++cp )
- if ( isspace( *cp ) )
- {
- ansi_style = TRUE;
- break;
- }
-
- if ( ansi_style )
- {
- /* save any trailing stuff */
- strcpy( temp, stop + 1 );
- /* remove end of current line */
- *start = '\0';
- /* rebuild line with arg names */
- strcat( buffer, " " );
- for ( i = 0; args[ i ]; ++i )
- {
- if ( i > 0 )
- strcat( buffer, ", " );
- strcat( buffer, argname( args[ i ] ) );
- }
- strcat( buffer, " )" );
- strcat( buffer, temp );
- /* flag that there are args to output */
- decflag = TRUE;
- }
- }
- else /* prototype */
- {
- if ( stop > start )
- strcpy( start, stop );
- }
- }
- }
- /*-------------------------------------------------------------------------
- argname( s ) finds the argument name in s and puts it in a local buffer,
- returning a pointer to it.
- -------------------------------------------------------------------------*/
- PRIVATE char *argname( s )
- char *s;
- {
- static char name[ 80 ];
- char *cp, *np, *strchr(), *strtok();
-
- strcpy( name, s ); /* get temp copy */
- if ( ( cp = strchr( name, '[' ) ) != NULL ) /* remove any [] */
- *cp = '\0';
- for ( cp = name; *cp; ++cp ) /* remove all non-id chars */
- if ( ! isid( *cp ) )
- *cp = ' ';
- np = NULL; /* find last valid name */
- for ( cp = name; ( cp = strtok( cp, " " ) ) != NULL; cp = NULL )
- np = cp;
- return( np ); /* return it */
- }
- /*-------------------------------------------------------------------------
- declarations( fo ) outputs all the declaration lines we saved from the
- function declaration. Called from outside this module.
- -------------------------------------------------------------------------*/
- declarations( fo )
- FILE *fo;
- {
- int i;
-
- for ( i = 0; args[ i ]; ++i )
- fprintf( fo, "%s;\n", args[ i ] );
- args[ 0 ] = NULL;
- }
- /*-------------------------------------------------------------------------
- isfunction( s ) returns TRUE if it thinks this line is a function declaration
- or prototype, or FALSE otherwise.
- -------------------------------------------------------------------------*/
- PRIVATE int isfunction( s )
- char *s;
- {
- char *cp, *strchr(), *strstr();
- int pnflag, pnlevel;
- int firstid, secondid, whitespace;
-
- /* should have at least one pair of parens with proper nesting */
- /* at least two identifiers prior to the opening paren */
- /* only certain non-identifier characters allowed */
- /* and nothing beyond final nesting paren except semicolon or comments */
- pnflag = FALSE;
- pnlevel = 0;
- firstid = secondid = whitespace = FALSE;
- for ( cp = s; *cp; ++cp )
- if ( ! isid( *cp ) )
- {
- if ( *cp == '(' )
- {
- pnflag = TRUE;
- ++pnlevel;
- }
- else if ( *cp == ')' )
- {
- if ( pnflag && pnlevel > 0 )
- {
- --pnlevel;
- if ( pnlevel == 0 )
- {
- /* check thru stuff after last nesting paren */
- for ( ++cp; *cp; ++cp )
- switch( *cp )
- {
- case '\t':
- case ' ':
- case ';':
- break;
- case '/':
- if ( *( cp + 1 ) == '*' )
- for ( cp += 2; *cp; ++cp )
- if ( *cp == '*' && *( cp + 1 ) == '/' )
- {
- ++cp;
- break;
- }
- break;
- default:
- #ifdef TESTING
- printf( "*** NOT A FUNCTION BECAUSE OF <%c> AFTER LAST PAREN ***\n", *cp );
- #endif
- return( FALSE );
- }
- break; /* stuff after parens is all ok */
- }
- }
- else
- {
- #ifdef TESTING
- printf( "*** NOT A FUNCTION BECAUSE PAREN NESTING IS BAD ***\n" );
- #endif
- return( FALSE );
- }
- }
- else if ( isspace( *cp ) )
- {
- if ( ! pnflag )
- if ( firstid && ! secondid )
- whitespace = TRUE;
- }
- else if ( strchr( "*,;[]", *cp ) == NULL )
- {
- #ifdef TESTING
- printf( "*** NOT A FUNCTION BECAUSE OF <%c> ***\n", *cp );
- #endif
- return( FALSE );
- }
- }
- else
- {
- if ( ! pnflag )
- if ( ! firstid )
- firstid = TRUE;
- else if ( whitespace )
- secondid = TRUE;
- }
-
- /* no parens at all? */
- if ( ! pnflag )
- {
- #ifdef TESTING
- printf( "*** NOT A FUNCTION BECAUSE THERE ARE NO PARENS ***\n" );
- #endif
- return( FALSE );
- }
-
- /* abnormal nesting result? */
- if ( pnlevel != 0 )
- {
- #ifdef TESTING
- printf( "*** NOT A FUNCTION BECAUSE PAREN NESTING IS BAD ***\n" );
- #endif
- return( FALSE );
- }
-
- /* bad id/whitespace sequence? */
- if ( ! firstid || ! whitespace || ! secondid )
- {
- #ifdef TESTING
- printf( "*** NOT A FUNCTION BECAUSE ID/WHITESPACE/PAREN SEQUENCE IS WRONG ***\n" );
- #endif
- return( FALSE );
- }
-
- /* 'else' keyword? */
- if ( ( cp = strstr( s, "else" ) ) != NULL )
- if ( cp == s || ! isid( *( cp - 1 ) ) )
- if ( ! isid( *( cp + 4 ) ) )
- {
- #ifdef TESTING
- printf( "*** NOT A FUNCTION BECAUSE OF 'ELSE' KEYWORD ***\n" );
- #endif
- return( FALSE );
- }
-
- /* 'return' keyword? */
- if ( ( cp = strstr( s, "return" ) ) != NULL )
- if ( cp == s || ! isid( *( cp - 1 ) ) )
- if ( ! isid( *( cp + 6 ) ) )
- {
- #ifdef TESTING
- printf( "*** NOT A FUNCTION BECAUSE OF 'RETURN' KEYWORD ***\n" );
- #endif
- return( FALSE );
- }
-
-
- #ifdef TESTING
- printf( "FUNCTION->>> " );
- #endif
- return( TRUE );
- }
- /*=======================================================================*/